"""
CMDB Models
"""
from django.db import models
from django.contrib.auth.models import User, Group


class Project(models.Model):
    """项目管理"""
    name = models.CharField(max_length=100, unique=True, verbose_name='项目名称')
    description = models.TextField(blank=True, verbose_name='项目描述')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '项目'
        verbose_name_plural = '项目'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.name


class Environment(models.Model):
    """环境管理"""
    ENV_CHOICES = [
        ('dev', '开发环境'),
        ('test', '测试环境'),
        ('staging', '预发布环境'),
        ('prod', '生产环境'),
    ]
    
    name = models.CharField(max_length=50, unique=True, verbose_name='环境名称')
    env_type = models.CharField(max_length=20, choices=ENV_CHOICES, verbose_name='环境类型')
    description = models.TextField(blank=True, verbose_name='环境描述')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '环境'
        verbose_name_plural = '环境'
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.name} ({self.get_env_type_display()})"


class HostGroup(models.Model):
    """主机组管理"""
    name = models.CharField(max_length=100, unique=True, verbose_name='主机组名称')
    description = models.TextField(blank=True, verbose_name='主机组描述')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '主机组'
        verbose_name_plural = '主机组'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.name


class Host(models.Model):
    """主机管理"""
    AUTH_TYPES = [
        ('password', '密码认证'),
        ('key', '密钥认证'),
    ]
    
    STATUS_CHOICES = [
        ('online', '在线'),
        ('offline', '离线'),
        ('unknown', '未知'),
    ]
    
    name = models.CharField(max_length=100, verbose_name='主机名称')
    ip = models.GenericIPAddressField(verbose_name='IP地址')
    mac_address = models.CharField(max_length=17, blank=True, verbose_name='MAC地址', 
                                    help_text='用于Wake-on-LAN远程开机，格式: 00:11:22:33:44:55')
    
    # IPMI配置（用于远程电源管理）
    ipmi_address = models.GenericIPAddressField(blank=True, null=True, verbose_name='IPMI地址',
                                                 help_text='IPMI/BMC管理地址，用于远程电源控制')
    ipmi_username = models.CharField(max_length=50, blank=True, verbose_name='IPMI用户名')
    ipmi_password = models.CharField(max_length=200, blank=True, verbose_name='IPMI密码')
    
    port = models.IntegerField(default=22, verbose_name='SSH端口')
    username = models.CharField(max_length=50, verbose_name='SSH用户名')
    
    auth_type = models.CharField(max_length=20, choices=AUTH_TYPES, default='password', verbose_name='认证方式')
    password = models.CharField(max_length=200, blank=True, verbose_name='SSH密码')
    ssh_key = models.TextField(blank=True, verbose_name='SSH私钥')
    
    project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, 
                                related_name='hosts', verbose_name='所属项目')
    environment = models.ForeignKey(Environment, on_delete=models.SET_NULL, null=True, blank=True,
                                    related_name='hosts', verbose_name='所属环境')
    host_group = models.ForeignKey(HostGroup, on_delete=models.SET_NULL, null=True, blank=True,
                                   related_name='hosts', verbose_name='所属主机组')
    
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='unknown', verbose_name='状态')
    description = models.TextField(blank=True, verbose_name='主机描述')
    
    # 系统信息
    os_type = models.CharField(max_length=50, blank=True, verbose_name='系统类型', 
                                help_text='如: Ubuntu, CentOS, RedHat, Debian')
    os_version = models.CharField(max_length=100, blank=True, verbose_name='系统版本',
                                   help_text='如: 22.04 LTS, 7.9, 8.5')
    os_kernel = models.CharField(max_length=100, blank=True, verbose_name='内核版本',
                                  help_text='如: 5.15.0-85-generic')
    
    # CPU信息
    cpu_cores = models.IntegerField(null=True, blank=True, verbose_name='CPU核心数',
                                     help_text='逻辑CPU核心数')
    cpu_arch = models.CharField(max_length=20, blank=True, verbose_name='CPU架构',
                                 help_text='如: x86_64, aarch64, armv7l')
    cpu_model = models.CharField(max_length=200, blank=True, verbose_name='CPU型号')
    
    # 内存信息
    memory_total = models.BigIntegerField(null=True, blank=True, verbose_name='内存总量(MB)',
                                          help_text='单位: MB')
    memory_used = models.BigIntegerField(null=True, blank=True, verbose_name='内存已使用(MB)',
                                         help_text='单位: MB')
    memory_info = models.CharField(max_length=100, blank=True, verbose_name='内存信息',
                                    help_text='如: 16GB, 32GB')
    
    # 磁盘信息
    disk_total = models.BigIntegerField(null=True, blank=True, verbose_name='磁盘总量(GB)',
                                        help_text='单位: GB')
    disk_used = models.BigIntegerField(null=True, blank=True, verbose_name='磁盘已使用(GB)',
                                       help_text='单位: GB')
    disk_info = models.CharField(max_length=100, blank=True, verbose_name='磁盘信息',
                                  help_text='如: 500GB SSD, 1TB HDD')
    
    # 网络信息
    public_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name='公网IP',
                                             help_text='ens33 公网网卡IP地址')
    private_ip = models.GenericIPAddressField(blank=True, null=True, verbose_name='内网IP',
                                              help_text='ens37 内网网卡IP地址')
    
    # 采集时间
    info_collected_at = models.DateTimeField(null=True, blank=True, verbose_name='信息采集时间',
                                             help_text='最后一次采集系统信息的时间')
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '主机'
        verbose_name_plural = '主机'
        ordering = ['-created_at']
        unique_together = ['ip', 'port']
    
    def __str__(self):
        return f"{self.name} ({self.ip}:{self.port})"


class UserProfile(models.Model):
    """用户扩展信息"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', verbose_name='用户')
    can_use_ssh = models.BooleanField(default=False, verbose_name='是否可以使用SSH')
    phone = models.CharField(max_length=20, blank=True, verbose_name='电话')
    department = models.CharField(max_length=100, blank=True, verbose_name='部门')
    avatar = models.TextField(blank=True, verbose_name='头像(Base64)')
    
    class Meta:
        verbose_name = '用户扩展信息'
        verbose_name_plural = '用户扩展信息'
    
    def __str__(self):
        return f"{self.user.username} 的扩展信息"


class EmailConfig(models.Model):
    """邮箱配置"""
    EMAIL_PROVIDER_CHOICES = [
        ('163', '163邮箱'),
        ('qq', 'QQ邮箱'),
        ('gmail', 'Gmail'),
        ('outlook', 'Outlook'),
        ('custom', '自定义'),
    ]
    
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='email_config', verbose_name='用户')
    email_provider = models.CharField(max_length=20, choices=EMAIL_PROVIDER_CHOICES, default='163', verbose_name='邮件服务商')
    email_address = models.EmailField(verbose_name='发件邮箱地址')
    smtp_server = models.CharField(max_length=100, default='smtp.163.com', verbose_name='SMTP服务器')
    smtp_port = models.IntegerField(default=465, verbose_name='SMTP端口')
    use_ssl = models.BooleanField(default=True, verbose_name='使用SSL')
    authorization_code = models.CharField(max_length=200, verbose_name='授权码')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '邮箱配置'
        verbose_name_plural = '邮箱配置'
    
    def __str__(self):
        return f"{self.user.username} 的邮箱配置 ({self.email_address})"


class AuditLog(models.Model):
    """审计日志"""
    LEVEL_CHOICES = [
        ('info', '信息'),
        ('warning', '警告'),
        ('error', '错误'),
        ('critical', '严重'),
    ]
    
    ACTION_CHOICES = [
        ('inspection_warning', '巡检警告'),
        ('host_offline', '主机离线'),
        ('threshold_exceeded', '阈值超出'),
        ('system_alert', '系统告警'),
        ('user_action', '用户操作'),
        ('dangerous_command', '危险命令'),
        ('sensitive_command', '敏感命令'),
        ('ssh_auth_failed', 'SSH认证失败'),
        ('ssh_connection_error', 'SSH连接错误'),
        ('file_download', '文件下载'),
    ]
    
    # 基本信息
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='时间戳', db_index=True)
    level = models.CharField(max_length=20, choices=LEVEL_CHOICES, default='info', verbose_name='日志级别', db_index=True)
    action = models.CharField(max_length=50, choices=ACTION_CHOICES, verbose_name='操作类型', db_index=True)
    
    # 主机信息
    host = models.ForeignKey(Host, on_delete=models.SET_NULL, null=True, blank=True, 
                             related_name='audit_logs', verbose_name='相关主机')
    host_ip = models.GenericIPAddressField(null=True, blank=True, verbose_name='主机IP')
    host_name = models.CharField(max_length=100, blank=True, verbose_name='主机名称')
    
    # 资源信息
    resource_type = models.CharField(max_length=50, blank=True, verbose_name='资源类型')  # cpu, memory, disk
    resource_value = models.FloatField(null=True, blank=True, verbose_name='资源使用率')  # percentage
    threshold = models.FloatField(null=True, blank=True, verbose_name='阈值')  # percentage
    
    # 详细信息
    title = models.CharField(max_length=200, verbose_name='标题')
    message = models.TextField(verbose_name='详细信息')
    
    # 用户信息
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True,
                            related_name='audit_logs', verbose_name='操作用户')
    
    # 额外数据（JSON格式）
    extra_data = models.JSONField(null=True, blank=True, verbose_name='额外数据')
    
    # 状态
    is_resolved = models.BooleanField(default=False, verbose_name='是否已解决')
    resolved_at = models.DateTimeField(null=True, blank=True, verbose_name='解决时间')
    resolved_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True,
                                    related_name='resolved_logs', verbose_name='解决人')
    
    class Meta:
        verbose_name = '审计日志'
        verbose_name_plural = '审计日志'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['-timestamp', 'level']),
            models.Index(fields=['host', '-timestamp']),
            models.Index(fields=['action', '-timestamp']),
        ]
    
    def __str__(self):
        return f"[{self.get_level_display()}] {self.title} - {self.timestamp.strftime('%Y-%m-%d %H:%M:%S')}"


class InspectionHistory(models.Model):
    """巡检历史记录"""
    # 基本信息
    host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name='inspection_histories', verbose_name='主机')
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name='巡检时间', db_index=True)
    
    # CPU信息
    cpu_usage = models.FloatField(verbose_name='CPU使用率(%)')
    cpu_core_count = models.IntegerField(null=True, blank=True, verbose_name='CPU核心数')
    cpu_frequency = models.FloatField(null=True, blank=True, verbose_name='CPU频率(MHz)')
    
    # 内存信息
    memory_usage = models.FloatField(verbose_name='内存使用率(%)')
    memory_total = models.FloatField(verbose_name='内存总量(GB)')
    memory_used = models.FloatField(verbose_name='已使用内存(GB)')
    memory_available = models.FloatField(verbose_name='可用内存(GB)')
    
    # 磁盘信息
    disk_usage = models.FloatField(verbose_name='磁盘使用率(%)')
    disk_total = models.FloatField(verbose_name='磁盘总量(GB)')
    disk_used = models.FloatField(verbose_name='已使用磁盘(GB)')
    disk_free = models.FloatField(verbose_name='剩余磁盘(GB)')
    disk_mount_point = models.CharField(max_length=100, default='/', verbose_name='挂载点')
    
    # 状态
    status = models.CharField(max_length=20, default='online', verbose_name='状态')
    has_warning = models.BooleanField(default=False, verbose_name='是否有警告')
    
    class Meta:
        verbose_name = '巡检历史'
        verbose_name_plural = '巡检历史'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['host', '-timestamp']),
            models.Index(fields=['-timestamp']),
        ]
    
    def __str__(self):
        return f"{self.host.name} - {self.timestamp.strftime('%Y-%m-%d %H:%M:%S')}"


class Role(models.Model):
    """角色模型"""
    ROLE_TYPE_CHOICES = [
        ('custom', '自定义角色'),
        ('system', '系统角色'),
    ]
    
    name = models.CharField(max_length=100, unique=True, verbose_name='角色名称')
    description = models.TextField(blank=True, verbose_name='描述')
    role_type = models.CharField(max_length=20, choices=ROLE_TYPE_CHOICES, default='custom', verbose_name='角色类型')
    permissions = models.JSONField(default=list, verbose_name='权限列表')
    user_groups = models.ManyToManyField('auth.Group', blank=True, related_name='roles', verbose_name='关联用户组')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    class Meta:
        verbose_name = '角色'
        verbose_name_plural = '角色'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.name
    
    @property
    def permission_count(self):
        """权限数量"""
        return len(self.permissions) if self.permissions else 0
    
    @property
    def user_group_ids(self):
        """关联的用户组ID列表"""
        return list(self.user_groups.values_list('id', flat=True))
    
    @property
    def user_group_names(self):
        """关联的用户组名称列表"""
        return list(self.user_groups.values_list('name', flat=True))
